package org.mii.safeguard_v1.base.web;

import javax.servlet.http.HttpServletRequest;

import org.extremecomponents.table.limit.Limit;
import org.mii.safeguard_v1.util.EcTablePageUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springside.modules.orm.Page;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;

/**
 * Struts2中典型CRUD Action的抽象基类.
 * 
 * 主要定义了对Preparable,ModelDriven接口的使用,以及CRUD函数和返回值的命名.
 * 
 * @param <T>
 *            CRUDAction所管理的对象类型.
 * 
 * @author calvin
 */
@SuppressWarnings("serial")
public abstract class CrudActionSupport<T> extends ActionSupport implements
		ModelDriven<T>, Preparable {

	/**
	 * 进行增删改操作后,以redirect方式重新打开action默认页的result名.
	 */
	public static final String RELOAD = "reload";
	/**
	 * 操作提示页的result名.
	 */
	public static final String NOTICE = "notice";
	/**
	 * 没有权限的定义
	 */
	public static final String DENY_ACCESS = "forbidden";

	/**
	 * ectable必须要设定的界面属性，放在本层可以所有action类公用
	 */
	public static final String TOTAL_ROWS = "totalRows";

	protected final Logger logger = LoggerFactory.getLogger(getClass());

	/**
	 * Action函数,默认action函数，默认指向list函数.
	 */
	@Override
	public String execute() throws Exception {
		return list();
	}

	// CRUD函数 //

	/**
	 * Action函数,显示Entity列表. 建议return SUCCESS.
	 */
	public abstract String list() throws Exception;

	/**
	 * Action函数,新增或修改Entity. 建议return RELOAD.
	 */
	public abstract String save() throws Exception;

	/**
	 * Action函数,删除Entity. 建议return RELOAD.
	 */
	public abstract String delete() throws Exception;

	// Preparable函数 //

	/**
	 * 实现空的prepare()函数,屏蔽所有Action函数公共的二次绑定.
	 */
	public void prepare() throws Exception {
	}

	/**
	 * 在save()前执行二次绑定.
	 */
	public void prepareSave() throws Exception {
		prepareModel();
	}

	/**
	 * 在input()前执行二次绑定.
	 */
	public void prepareInput() throws Exception {
		prepareModel();
	}

	/**
	 * 等同于prepare()的内部函数,供prepardMethodName()函数调用.
	 */
	protected abstract void prepareModel() throws Exception;

	// ///////////////// 为适应ecTable分页而设置的方法

	/**
	 * 设置分页Page的属性，如果采用ectable作为界面展示，需要调用该方法设置属性
	 * 
	 * @author QUANXIWEI
	 */
	protected void setPageParamters(Page<T> page, HttpServletRequest request) {
		Limit limit = EcTablePageUtil.getLimit(request, null);
		page.setPageNo(limit.getPage());
		page.setPageSize(limit.getCurrentRowsDisplayed());
	}
}
